/* test.cc */
#include <boost/mpi.hpp>
#include <iostream>
#include <fstream>
#include <functional>
#include <boost/serialization/string.hpp>
#include <boost/math/special_functions/log1p.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/program_options.hpp>

using namespace boost;
using namespace std;
using namespace boost::posix_time;
namespace po = boost::program_options;

void genData(const po::variables_map& vm);
const int n = 4096;

int main(int argc, char* argv[])
{
  mpi::environment env(argc, argv);
  mpi::communicator world;
  
  cout << "rank = " << world.rank() << "\n";
  po::variables_map vm;
  po::options_description desc("Allowed options");
  desc.add_options()
    ("help", "proceduce help message")
    ("gen", po::value<int>()->default_value(0), "is generating data ?")
    ("data", po::value<string>()->default_value("vec.bin"), 
     "file name for data");
  po::store(po::parse_command_line(argc, argv, desc), vm);
  po::notify(vm);

  if (vm["gen"].as<int>() == 1)
  {
    if (world.rank()==0) genData(vm);
    return 0;
  }

  int rank = world.rank(), max_rank, n_local, begin_pos;
  mpi::all_reduce(world, rank, max_rank, mpi::maximum<int>());
  if (n % (max_rank+1) == 0)
  n_local = n / (max_rank+1) + 1;
  begin_pos = rank*n_local;
  n_local = n-begin_pos < n_local ? n-begin_pos : n_local;
  cout << "I know max rank = " << max_rank << "\n";
  
  double *x = new double[n_local];
  long long s_local = 0;
  for (int
  

  return 0;
}

void genData(const po::variables_map& vm)
{
  cout << "master process is generating data ...\n";
  double x[n];
  for (int i = 0; i < n; i++) x[i] = i;
  ofstream f;
  f.open(vm["data"].as<string>().c_str(), ios::binary);
  f.write((char*)x, sizeof(double)*n);
  f.close();
}
